package org.kermeta.spem.activityautomation.eclipse.validateemfmodel.actions;

import java.util.Iterator;
import java.util.Map;

import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.kermeta.spem.activityautomationmanager.Activator;
import org.kermeta.spem.executioncontext.ExecutionContext;
import org.kermeta.spem.executioncontext.ExecutioncontextPackage;
import org.kermeta.spem.executioncontext.Key;

public class ValidateEMFModel {

	/**
	 * The constructor.
	 */
	public ValidateEMFModel() {
	}

	public void run(Shell shell) {
	}

	public void run(Shell shell, String contextModelPath) {
		String projectName = null;
		String metamodelName = null;
		EObject metamodelRoot = null;

		//Read the project name and the metamodel name into the context model
		// Initialize the model
		ExecutioncontextPackage.eINSTANCE.eClass();

		// Register the XMI resource factory for the .executioncontext extension

		Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
		Map<String, Object> m = reg.getExtensionToFactoryMap();
		m.put("executioncontext", new XMIResourceFactoryImpl());

		// Obtain a new resource set
		ResourceSet resSet = new ResourceSetImpl();

		// Get the resource
		Resource resource = resSet.getResource(URI
				.createURI(contextModelPath), true);
		// Get the first model element and cast it to the right type, in my
		// example everything is hierarchical included in this first node
		ExecutionContext executionContext = (ExecutionContext) resource.getContents().get(0);

		for(Key key: executionContext.getKeys()){
			if(key.getName().equals("project name")){
				projectName = key.getValue().getContent();
			}
			if(key.getName().equals("model file name")){
				metamodelName = key.getValue().getContent();
			}
		}

		//Get the root of the metamodel
		// Initialize the model
		EcorePackage.eINSTANCE.eClass();

		// Register the XMI resource factory for the .ecore extension

		Resource.Factory.Registry reg2 = Resource.Factory.Registry.INSTANCE;
		Map<String, Object> m2 = reg2.getExtensionToFactoryMap();
		m2.put("ecore", new XMIResourceFactoryImpl());

		// Obtain a new resource set
		ResourceSet resSet2 = new ResourceSetImpl();

		// Get the resource
		Resource resource2 = resSet2.getResource(URI
				.createURI("/"+projectName+"/model/"+metamodelName+".ecore"), true);
		// Get the first model element and cast it to the right type, in my
		// example everything is hierarchical included in this first node
		metamodelRoot = resource2.getContents().get(0);

		//Validate the metamodel
		Diagnostic diagnostic = Diagnostician.INSTANCE.validate(metamodelRoot);

		if (diagnostic.getSeverity() == Diagnostic.ERROR)
		{
			String errors = "";
			for (Iterator i=diagnostic.getChildren().iterator(); i.hasNext();)
			{
				Diagnostic childDiagnostic = (Diagnostic)i.next();
				switch (childDiagnostic.getSeverity())
				{
				case Diagnostic.ERROR:
					errors = errors.concat("\n"+ childDiagnostic.getMessage());
				}
			}
			Status status = new Status(IStatus.ERROR, Activator.getDefault().PLUGIN_ID, 0,
		            errors, null);
			ErrorDialog.openError(
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
					"Metamodel validation",
					diagnostic.getMessage()+": errors exist in the metamodel.",
					status);
		}

		if (diagnostic.getSeverity() == Diagnostic.WARNING)
		{
			String warnings = "";
			for (Iterator i=diagnostic.getChildren().iterator(); i.hasNext();)
			{
				Diagnostic childDiagnostic = (Diagnostic)i.next();
				switch (childDiagnostic.getSeverity())
				{
				case Diagnostic.WARNING:
					warnings = warnings.concat("\n"+ childDiagnostic.getMessage());
				}
			}
			Status status = new Status(IStatus.WARNING, Activator.getDefault().PLUGIN_ID, 0,
		            warnings, null);
			ErrorDialog.openError(
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
					"Metamodel validation",
					diagnostic.getMessage()+": warnings exist in the metamodel.",
					status);
		}

		if (diagnostic.getSeverity() == Diagnostic.OK)
		{
			MessageDialog.openInformation(
					shell,
					"Metamodel validation",
					diagnostic.getMessage()+": the model is valid.");
		}
	}
}